﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.IO;
using System.Globalization;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Net;


namespace DataToShow.Network
{
    public delegate void ShowConnectSateEventHandler(bool isValue);
    public class AgreementHandler
    {
        private M_Agreement model;
        private NetworkStream netStream;
        private string strPack;
        private string temp = string.Empty;
        private static object obj = new object();
        #region  Construction method
        /// <summary>
        /// 数据包（字符串的格式）注：处理接收到的信息
        /// </summary>
        /// <param name="strPack"></param>
        public AgreementHandler(string strPack)
        {
            this.strPack = strPack;

        }
        /// <summary>
        /// 无参构造方法 注：用于处理接收到的信息（异步读取）
        /// </summary>
        public AgreementHandler()
        {
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="model"></param>
        public AgreementHandler(M_Agreement model)
        {
            this.model = model;
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="message">要发送的内容</param>
        /// <param name="commandType">命令字</param>
        /// <param name="sendType">传送类型</param>
        /// <param name="dataType">数据原始类型</param>
        public AgreementHandler(string strID, string message, CommandType commandType, NetworkStream netStream)
        {
            model = new M_Agreement(strID, commandType, message);
            this.netStream = netStream;
        }

        public AgreementHandler(string message, CommandType commandType, NetworkStream netStream)
        {
            model = new M_Agreement(commandType, message);
            this.netStream = netStream;
        }
        /// <summary>
        /// 构造方法 （可以DLL方式使用 目前不采用）
        /// </summary>
        /// <param name="mStream"></param>
        public AgreementHandler(NetworkStream netStream)
        {
            this.netStream = netStream;
        }


        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="model"></param>
        public AgreementHandler(M_Agreement model, NetworkStream netStream)
        {
            this.model = model;
            this.netStream = netStream;
        }



        #endregion

        #region private method



        /// <summary>
        /// 对接收到的信息进行分析
        /// </summary>
        /// <param name="strPack"></param>
        /// <returns></returns>
        private M_Agreement[] stringAnalysis(string strPack)
        {
            int[] list = Regex.Matches(strPack, "CRCFF").OfType<Match>().Select(t => t.Index).ToArray();
            if (list.Length == 0)
                return new M_Agreement[] { new M_Agreement() };
            string msg = strPack.Replace("CRCFF", "∈");
            string[] strArr = msg.Split('∈');
            M_Agreement[] models = new M_Agreement[strArr.Length - 1];
            for (int i = 0; i < models.Length; i++)
            {
                models[i] = stringToModel(strArr[i]);
            }
            return models;
        }

        /// <summary>
        /// 将数据包解释成model
        /// </summary>
        /// <param name="value">数据包</param>
        /// <returns></returns>
        private M_Agreement stringToModel(string value)
        {
            M_Agreement newModel = new M_Agreement();
            if (value != "" || value != null)
            {
                string ss = value.Substring(4, 2);
                newModel.MsgCommandType = (CommandType)Enum.ToObject(typeof(CommandType), Convert.ToInt32(value.Substring(4, 2), 16));
                newModel.Message = value.Substring(6, value.Length - 6);
                newModel.strID = value.Substring(0, 4);
                return newModel;
            }
            else
            {
                return newModel;
            }
        }
        #endregion

        #region   public method
        /// <summary>
        /// 根据接收的信息分析获得包的mode形式
        /// </summary>
        /// <returns></returns>
        public M_Agreement[] GetM_AgreementArray()
        {
            return stringAnalysis(strPack);
        }
        /// <summary>
        /// 根据接收的信息分析获得包的mode形式 (为使用无参构造方法使用)
        /// </summary>
        /// <returns></returns>
        public M_Agreement[] GetM_AgreementArray(string strPack)
        {
            this.strPack = strPack;

            return stringAnalysis(strPack);
        }


        /// <summary>
        ///  获得流
        /// </summary>
        /// <returns></returns>
        public MemoryStream GetStream()
        {
            MemoryStream ms = new MemoryStream();
            XmlSerializer serializer = new XmlSerializer(typeof(M_Agreement));
            serializer.Serialize(ms, model);
            ms.Seek(0, SeekOrigin.Begin);
            return ms;
        }
        /// <summary>
        /// 获得流字节数组
        /// </summary>
        /// <param name="encoder"></param>
        /// <returns></returns>
        public byte[] GetBuffer()
        {
            //创建内存流
            MemoryStream memStream = new MemoryStream();
            //产生二进制序列化格式
            IFormatter formatter = new BinaryFormatter();
            //串行化到内存中
            formatter.Serialize(memStream, model);
            byte[] binaryResult = memStream.ToArray();
            //清空和释放内存流
            memStream.Close();
            memStream.Dispose();
            return binaryResult;
        }
        /// <summary>
        /// 获得当前M_Agreement实例
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public M_Agreement GetM_Agreement(byte[] buffer)
        {
            MemoryStream memStream = new MemoryStream(buffer);

            //产生二进制序列化格式
            IFormatter formatter = new BinaryFormatter();
            //反串行化到内存中
            object obj = formatter.Deserialize(memStream);
            //类型检验
            if (obj is M_Agreement)
            {
                M_Agreement Result = (M_Agreement)obj;
                return Result;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 获得当前M_Agreement实例
        /// </summary>
        /// <returns></returns>
        public M_Agreement GetM_Agreement()
        {
            return model;
        }
        /// <summary>
        /// 读信息(通讯编码为Unicode) 供带networkstream 参数的实例使用
        /// </summary>
        public M_Agreement[] Read()
        {
            byte[] buffer = new byte[32768];
            int count = netStream.Read(buffer, 0, 32768);
            string msg = Encoding.UTF8.GetString(buffer, 0, count);
            M_Agreement[] modelArray = GetM_AgreementArray(msg);
            return modelArray;
        }
        /// <summary>
        /// 读信息(通讯编码为Unicode) 供带networkstream 参数的实例使用
        /// </summary>
        /// <param name="encoder"></param>
        /// <returns></returns>
        public M_Agreement[] Read(Encoding encoder)
        {
            byte[] buffer = new byte[32768];
            int count = netStream.Read(buffer, 0, 32768);
            string msg = encoder.GetString(buffer, 0, count);
            M_Agreement[] modelArray = GetM_AgreementArray(msg);
            return modelArray;
        }
        /// <summary>
        /// 发送信息(通讯编码为Unicode)
        /// </summary>
        public void Send()
        {
            string message = GetMessagePack();
            byte[] buffer = Encoding.UTF8.GetBytes(message);
            int count = buffer.Length;
            netStream.Write(buffer, 0, buffer.Length);

        }

        /// <summary>
        /// 读取信息,采用(通讯编码为UTF-8),方式，在网络中传输. 供带networkstream 参数的实例使用
        /// </summary>
        public M_Agreement[] Read(ShowConnectSateEventHandler ShowConnectSate)
        {
            lock (obj)
            {
                byte[] buffer = new byte[32768];
                int bytesRead = 0;          // 读取的字节数
                string msg = "";
                do
                {
                    try
                    {
                        bytesRead = netStream.Read(buffer, 0, 32768);
                        msg += Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        ShowConnectSate(true);
                    }
                    catch
                    {
                        ShowConnectSate(false);
                    }
                    // msStream.Write(buffer, 0, bytesRead);
                } while (bytesRead >= 32768);
                //获得16进制表示的 协议包组
                // string msg = Encoding.UTF8.GetString(nbuffer, 0, nbuffer.Length);
                M_Agreement[] modelArray = GetM_AgreementArray(msg);
                return modelArray;
            }
        }
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="encoder"></param>
        public void send(Encoding encoder)
        {
            string message = model.GetCompeteString();
            byte[] buffer = encoder.GetBytes(message);
            // byte[] buffer = GetBuffer();
            netStream.Write(buffer, 0, buffer.Length);
            // Console.WriteLine("返回客户端的数据:"+message);
        }
        /// <summary>
        /// 发送信息[组装好的16进制协议包组,  采用，，](通讯编码为UTF-8)方式，在网络中传输
        /// </summary>
        /// <param name="ShowConnectSate"></param>
        public void Send(ShowConnectSateEventHandler ShowConnectSate)
        {
            string message = GetMessagePack();
            byte[] buffer = Encoding.UTF8.GetBytes(message);
            lock (obj)
            {
                try
                {
                    netStream.Write(buffer, 0, buffer.Length);
                    ShowConnectSate(true);
                }
                catch
                {
                    ShowConnectSate(false);
                }
            }
        }

        /// <summary>
        /// 按协议生成16进制字符串
        /// </summary>
        /// <returns></returns>
        public string GetMessagePack()
        {
            return model.GetCompeteString();

        }
        /// <summary>
        /// 获得信息
        /// </summary>
        /// <returns></returns>
        public string GetMessage()
        {
            string hexString = model.GetMessage();
            return hexString;
        }
        #endregion
    }
}
